/**
 * MCP API Routes
 * 
 * Handles MCP server management (list, register, unregister)
 */

import { Hono } from 'hono';
import type { ApiResponse, McpServerConfig } from '@/types';
import { logger } from '@/utils/logger';

export const mcpRoutes = new Hono();

// In-memory MCP server registry (TODO: Replace with persistent storage)
const mcpServers = new Map<string, McpServerConfig>();

/**
 * GET /api/mcp/servers
 * 
 * List all registered MCP servers
 */
mcpRoutes.get('/servers', (c) => {
  const allServers = Array.from(mcpServers.entries()).map(([name, config]) => ({
    name,
    type: config.type,
    config,
  }));

  const response: ApiResponse = {
    success: true,
    data: allServers,
    timestamp: new Date().toISOString(),
  };

  return c.json(response);
});

/**
 * GET /api/mcp/servers/:name
 * 
 * Get MCP server details
 */
mcpRoutes.get('/servers/:name', (c) => {
  const serverName = c.req.param('name');

  const server = mcpServers.get(serverName);

  if (!server) {
    const response: ApiResponse = {
      success: false,
      error: {
        code: 'MCP_SERVER_NOT_FOUND',
        message: `MCP server ${serverName} not found`,
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 404);
  }

  const response: ApiResponse = {
    success: true,
    data: {
      name: serverName,
      type: server.type,
      config: server,
    },
    timestamp: new Date().toISOString(),
  };

  return c.json(response);
});

/**
 * POST /api/mcp/servers
 * 
 * Register a new MCP server
 */
mcpRoutes.post('/servers', async (c) => {
  try {
    const body = await c.req.json();
    const { name, config } = body;

    // Validate request
    if (!name || !config || !config.type) {
      const response: ApiResponse = {
        success: false,
        error: {
          code: 'INVALID_REQUEST',
          message: 'Missing required fields: name, config.type',
        },
        timestamp: new Date().toISOString(),
      };
      return c.json(response, 400);
    }

    // Check if server already exists
    if (mcpServers.has(name)) {
      const response: ApiResponse = {
        success: false,
        error: {
          code: 'MCP_SERVER_ALREADY_EXISTS',
          message: `MCP server ${name} already exists`,
        },
        timestamp: new Date().toISOString(),
      };
      return c.json(response, 409);
    }

    // Validate config based on type
    const validatedConfig = validateMcpConfig(config);
    if (!validatedConfig) {
      const response: ApiResponse = {
        success: false,
        error: {
          code: 'INVALID_MCP_CONFIG',
          message: `Invalid MCP server configuration for type ${config.type}`,
        },
        timestamp: new Date().toISOString(),
      };
      return c.json(response, 400);
    }

    // Register server
    mcpServers.set(name, validatedConfig);

    logger.info('MCP server registered', { name, type: config.type });

    const response: ApiResponse = {
      success: true,
      data: { name, type: config.type, registered: true },
      timestamp: new Date().toISOString(),
    };

    return c.json(response);
  } catch (error) {
    logger.error('Failed to register MCP server', error);

    const response: ApiResponse = {
      success: false,
      error: {
        code: 'MCP_SERVER_REGISTER_ERROR',
        message: error instanceof Error ? error.message : 'Unknown error',
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 500);
  }
});

/**
 * DELETE /api/mcp/servers/:name
 * 
 * Unregister an MCP server
 */
mcpRoutes.delete('/servers/:name', (c) => {
  const serverName = c.req.param('name');

  const existed = mcpServers.delete(serverName);

  if (!existed) {
    const response: ApiResponse = {
      success: false,
      error: {
        code: 'MCP_SERVER_NOT_FOUND',
        message: `MCP server ${serverName} not found`,
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 404);
  }

  logger.info('MCP server unregistered', { name: serverName });

  const response: ApiResponse = {
    success: true,
    data: { name: serverName, deleted: true },
    timestamp: new Date().toISOString(),
  };

  return c.json(response);
});

/**
 * Validate MCP server configuration
 */
function validateMcpConfig(config: any): McpServerConfig | null {
  switch (config.type) {
    case 'stdio':
      if (!config.command) return null;
      return config as McpServerConfig;
    
    case 'sse':
    case 'http':
      if (!config.url) return null;
      return config as McpServerConfig;
    
    case 'sdk':
      if (!config.name) return null;
      return config as McpServerConfig;
    
    default:
      return null;
  }
}

